package com.baidu.health.service;

import com.alibaba.fastjson.JSON;
import com.baidu.health.mapper.TbCommentMapper;
import com.baidu.health.mapper.TbDocumentMapper;
import com.baidu.health.pojo.TbComment;
import com.baidu.health.pojo.TbDocument;
import com.baidu.health.pojo.TbSensitivity;
import com.baidu.health.pojo.resultVo.articleContentVo;
import com.baidu.health.pojo.resultVo.articleVo;
import com.baidu.health.pojo.resultVo.resultVo;
import com.baidu.health.utils.KeyWordFilter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baidu.health.pojo.TbArticle;
import com.baidu.health.mapper.TbArticleMapper;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class TbArticleServiceImpl extends ServiceImpl<TbArticleMapper, TbArticle>{

    @Autowired
    TbArticleMapper articleMapper;

    @Autowired
    TbCommentMapper commentMapper;

    @Autowired
    TbDocumentMapper documentMapper;

    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Scheduled(cron = "* 0/20 * * * ?")
    public void sync()throws Exception {
        List<TbArticle> list = articleMapper.selectList(new QueryWrapper<TbArticle>());

        BulkRequest request = new BulkRequest();

        for (int i = 0; i < list.size(); i++) {
            request.add(
                    new IndexRequest("health")
                    .id(list.get(i).getArticleId()+"")
                    .source(JSON.toJSONString(list.get(i)), XContentType.JSON)
            );
        }

        restHighLevelClient.bulk(request, RequestOptions.DEFAULT);

    }

    public List<TbSensitivity> getTbSensitivityList() throws Exception{
        SearchRequest request = new SearchRequest("min");
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());
        builder.size(5000);
        request.source(builder);
        SearchHit[] hits = restHighLevelClient.search(request, RequestOptions.DEFAULT).getHits().getHits();
        List<TbSensitivity> list = new ArrayList<>();
        for (SearchHit hit : hits) {
            TbSensitivity parseObject = JSON.parseObject(hit.getSourceAsString(), TbSensitivity.class);
            list.add(parseObject);
        }
        return list;
    }

    public articleVo addArticle(TbArticle article) throws Exception {

        articleMapper.insert(article);
        this.sync();

        TbDocument document = new TbDocument();
        document.setArticleId(article.getArticleId());
        document.setArticleTitle(article.getArticleTitle());
        document.setDocumentSrc(article.getArticleFile());

        documentMapper.insert(document);

        rabbitTemplate.convertAndSend("rticleExchanges","article",article);

        return new articleVo(true,200,"添加成功",null,null);
    }

    public articleVo getArticleList(Integer pageNum, Integer pageSize, TbArticle article) throws Exception {

        SearchRequest request = new SearchRequest("health");
        SearchSourceBuilder builder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();

        if ( article.getArticleTitle() != null && !article.getArticleTitle().equals("") ){
//            builder.query(QueryBuilders.matchQuery("articleTitle",article.getArticleTitle()));
            boolQueryBuilder.must(QueryBuilders.termQuery("articleTitle",article.getArticleTitle())).must(QueryBuilders.termQuery("delFlag",0)).must(QueryBuilders.termQuery("checkFlag",0));
        }else {
            boolQueryBuilder.must(QueryBuilders.termQuery("delFlag",0)).must(QueryBuilders.termQuery("checkFlag",0));
        }

        builder.query(boolQueryBuilder);

        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("articleTitle");
        highlightBuilder.preTags("<strong style=color:'red'>");
        highlightBuilder.postTags("</strong>");
        builder.highlighter(highlightBuilder);

        builder.from((pageNum-1)*pageSize);
        builder.size(pageSize);

        request.source(builder);

        SearchHits hits = restHighLevelClient.search(request, RequestOptions.DEFAULT).getHits();

        long total = hits.getTotalHits().value;

        List<TbArticle> list = new ArrayList<>();

        for (SearchHit hit : hits.getHits()) {
            TbArticle tbArticle = JSON.parseObject(hit.getSourceAsString(), TbArticle.class);
            Map<String, HighlightField> map = hit.getHighlightFields();
            if ( map.size() > 0 ){
                tbArticle.setArticleTitle(map.get("articleTitle").getFragments()[0].toString());
            }
            list.add(tbArticle);
        }

        return new articleVo(true,200,"查询成功",list,Integer.parseInt(total+""));

    }

    public articleVo deleteArticle(TbArticle article) {
//        article.setDelFlag(1);
        articleMapper.deleteById(article);
        try {
            this.sync();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new articleVo(true,200,"删除成功",null,null);
    }

    public articleVo updateArticle(TbArticle article) throws Exception{
        KeyWordFilter keyWordFilter = new KeyWordFilter();

        boolean checkTitle = keyWordFilter.doFilter(article.getArticleTitle());
        boolean checkContent = keyWordFilter.doFilter(article.getArticleContent());

        if ( checkTitle && checkContent ){
            articleMapper.updateById(article);
            this.sync();
            return new articleVo(true,200,"修改成功",null,null);
        }else {
            return new articleVo(false,500,"包含敏感词，请及时处理",null,null);
        }
    }

    public articleContentVo getArticleContent(Integer articleId) {

        TbArticle tbArticle = articleMapper.selectOne(new QueryWrapper<TbArticle>().lambda().eq(TbArticle::getArticleId, articleId));

        tbArticle.setArticleBrowseNums(tbArticle.getArticleBrowseNums() + 1);

        articleMapper.updateById(tbArticle);

        QueryWrapper<TbComment> wrapper = new QueryWrapper<>();

        wrapper.lambda().eq(TbComment::getArticleId,articleId);
        wrapper.lambda().eq(TbComment::getFatherId,0);
        wrapper.lambda().eq(TbComment::getCheckFlag,1);

        List<TbComment> comments = commentMapper.selectList(wrapper);

        return new articleContentVo(200,"查看文章内容",tbArticle,comments);

    }

    public articleVo getArticleLists(Integer pageNum, Integer pageSize)throws Exception {
//        SearchRequest request = new SearchRequest("health");
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        builder.query(QueryBuilders.matchQuery("delFlag",0));
//        builder.from((pageNum-1)*pageSize);
//        builder.size(pageSize);
//        request.source(builder);
//        SearchHits hits = restHighLevelClient.search(request, RequestOptions.DEFAULT).getHits();
//        long total = hits.getTotalHits().value;
//        List<TbArticle> list = new ArrayList<>();
//        for (SearchHit hit : hits.getHits()) {
//            TbArticle tbArticle = JSON.parseObject(hit.getSourceAsString(), TbArticle.class);
//            list.add(tbArticle);
//        }

        Page<TbArticle> page = new Page<>(pageNum, pageSize);
        Page<TbArticle> articlePage = articleMapper.selectPage(page, new QueryWrapper<TbArticle>().lambda().eq(TbArticle::getCheckFlag,0));

        return new articleVo(true,200,"查询成功",articlePage,Integer.parseInt(articlePage.getTotal()+""));
    }

    public resultVo checkArticle(Integer articleStatus,TbArticle article)throws Exception {
        article.setUpdateTime(new Date());
        article.setCheckFlag(articleStatus);
        articleMapper.updateById(article);
        this.sync();
        return new resultVo(200,"审核完成",null);
    }
}




